package com.flashmoment.video.controller;

import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.flashmoment.video.entity.VideoEntity;
import com.flashmoment.video.service.UserConcernsService;
import com.flashmoment.video.service.VideoService;
import com.flashmoment.video.utils.Constant;
import com.flashmoment.video.utils.JwtUtils;
import com.flashmoment.video.utils.PageUtils;
import com.flashmoment.video.utils.R;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;

import com.flashmoment.video.entity.UserEntity;
import com.flashmoment.video.service.UserService;

import javax.servlet.http.HttpServletRequest;


/**
 * 用户表
 *
 * @author xulu
 * @email 1435533194@qq.com
 * @date 2023-10-24 16:35:33
 */
@CrossOrigin
@RestController
@RequestMapping("video/user")
@Slf4j
@Api(tags = "用户接口")
public class UserController {
    @Autowired
    private UserService userService;

    @Autowired
    private VideoService videoService;

    @Autowired
    private UserConcernsService userConcernsService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 列表
     */
    @RequestMapping("/list")
    public R list(@RequestParam Map<String, Object> params) {
        PageUtils page = userService.queryPage(params);

        return R.ok().put("page", page);
    }


    /**
     * 信息
     */
    @RequestMapping("/info/{id}")
    public R info(@PathVariable("id") Long id) {
        UserEntity user = userService.getById(id);

        return R.ok().put("user", user);
    }

    /**
     * 保存
     */
    @RequestMapping("/save")
    public R save(@RequestBody UserEntity user) {
        userService.save(user);

        return R.ok();
    }

    /**
     * 修改
     */
    @RequestMapping("/update")
    public R update(@RequestBody UserEntity user) {
        userService.updateById(user);

        return R.ok();
    }

    /**
     * 删除
     */
    @RequestMapping("/delete")
    public R delete(@RequestBody Long[] ids) {
        userService.removeByIds(Arrays.asList(ids));

        return R.ok();
    }

    /**
     * 用户注册
     *
     * @param map
     * @return
     */
    @PostMapping("/register")
    public R register(@RequestBody Map<String, Object> map) {

        String code = (String) map.get("code");
        String email = (String) map.get("email");

        try {
            if (!code.equals(stringRedisTemplate.opsForValue().get(email)) || StringUtils.isBlank(code)) {
                return Objects.requireNonNull(new R().put("code", Constant.FAILURE_CODE)).put("message", Constant.CODE_ERROR);
            }
            UserEntity userEntity = new UserEntity();
            userEntity.setUsername((String) map.get("username"));
            userEntity.setEmail(email);
            String password = (String) map.get("password");
            userEntity.setPassword(DigestUtils.md5DigestAsHex((password).getBytes(StandardCharsets.UTF_8)));

            if (Boolean.TRUE.equals(stringRedisTemplate.opsForSet().isMember("registered_users", email))) {
                return Objects.requireNonNull(new R().put("code", Constant.FAILURE_CODE)).put("message", Constant.USER_EXIST);
            } else {
                boolean flag = userService.save(userEntity);
                if (flag) {
                    stringRedisTemplate.opsForSet().add("registered_users", email);
                } else {
                    return Objects.requireNonNull(new R().put("code", Constant.FAILURE_CODE)).put("message", Constant.REGISTER_FAULURE);
                }

            }
        } catch (Exception e) {
            log.info("用户注册:{}", e.getMessage());
        }
        return Objects.requireNonNull(new R().put("code", Constant.SUCCESS_CODE)).put("message", Constant.REGISTER_SUCCESS);
    }

    /**
     * 用户登录
     *
     * @param map
     * @return
     */
    @PostMapping("/login")
    private R login(@RequestBody Map<String, Object> map) {
        String codePassword = (String) map.get("codePassword");
        String emailNumber = (String) map.get("emailNumber");
        String emailPassword = (String) map.get("emailPassword");
        UserEntity user = null;
        try {
            if (userService.findUserCount(emailNumber)<1) {
                return Objects.requireNonNull(new R().put("code", Constant.FAILURE_CODE)).put("message", Constant.USER_NOT_EXIST);
            } else {
                user = userService.findUserByEmail(emailNumber);

                if (org.apache.commons.lang.StringUtils.isNotBlank(codePassword)) {
                    if (!codePassword.equals(stringRedisTemplate.opsForValue().get(emailNumber))) {
                        return Objects.requireNonNull(new R().put("code", Constant.FAILURE_CODE)).put("message", Constant.CODE_ERROR);
                    }
                } else if (org.apache.commons.lang.StringUtils.isNotBlank(emailPassword)) {
                    if (!DigestUtils.md5DigestAsHex((emailPassword).getBytes(StandardCharsets.UTF_8)).equals(user.getPassword())) {
                        return Objects.requireNonNull(new R()
                                .put("code", Constant.FAILURE_CODE)).put("message", Constant.PASSWORD_ERROR);
                    }
                }
            }


        } catch (Exception e) {
            log.info("用户登录:{}", e.getMessage());
            return Objects.requireNonNull(Objects.requireNonNull(Objects.requireNonNull(new R().put("code", Constant.FAILURE_CODE)).put("message", Constant.LOGIN_FAILURE)));

        }

        user.setPassword("");

        return Objects.requireNonNull(Objects.requireNonNull(Objects.requireNonNull(new R().put("code", Constant.SUCCESS_CODE)).put("message", Constant.LOGIN_SUCCESS)).put("token", JwtUtils.createToken(user.getEmail()))).put("user", user);

    }

    /**
     * 忘记密码
     *
     * @param map
     * @return
     */
    @PostMapping("/forgetPassword")
    public R forgetPassword(@RequestBody Map<String, Object> map) {
        String emailNumber = (String) map.get("emailNumber");
        String password = (String) map.get("password");
        String code = (String) map.get("code");
        UserEntity user = userService.findUserByEmail(emailNumber);
        if (!code.equals(stringRedisTemplate.opsForValue().get(emailNumber))) {
            return Objects.requireNonNull(new R().put("code", Constant.FAILURE_CODE)).put("message", Constant.CODE_ERROR);
        } else if (DigestUtils.md5DigestAsHex(password.getBytes(StandardCharsets.UTF_8)).equals(user.getPassword())) {
            return Objects.requireNonNull(new R().put("code", Constant.FAILURE_CODE)).put("message", Constant.PASSWORD_REPEAT);
        }
        if (org.apache.commons.lang.StringUtils.isNotBlank(emailNumber) && org.apache.commons.lang.StringUtils.isNotBlank(password)) {
            userService.updatePasswordByEmail(emailNumber, DigestUtils.md5DigestAsHex(password.getBytes(StandardCharsets.UTF_8)),DateUtil.date());
        }
        return Objects.requireNonNull(new R().put("code", Constant.SUCCESS_CODE)).put("message", Constant.UPDATE_PASSWORD_SUCCESS);
    }


    /**
     * 修改密码
     *
     * @param map
     * @return
     */
    @PostMapping("/updatePassword")
    public R updatePassword(@RequestBody Map<String, Object> map) {
        String email = (String) map.get("emailNumber");
        String updatePassword = (String) map.get("updatePassword");
        String code = (String) map.get("code");
        String id = (String) map.get("id");
        UserEntity user = new UserEntity();
        UserEntity userEntity = userService.findUserByEmail(email);

        try {
            if (!code.equals(stringRedisTemplate.opsForValue().get(email))) {
                return Objects.requireNonNull(new R().put("code", Constant.FAILURE_CODE)).put("message", Constant.CODE_ERROR);
            } else if (DigestUtils.md5DigestAsHex(updatePassword.getBytes(StandardCharsets.UTF_8)).equals(userEntity.getPassword())) {
                return Objects.requireNonNull(new R().put("code", Constant.FAILURE_CODE)).put("message", Constant.PASSWORD_REPEAT);
            }
            user.setId(Long.parseLong(id));
            user.setPassword(DigestUtils.md5DigestAsHex(updatePassword.getBytes(StandardCharsets.UTF_8)));
            userService.updateById(user);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return Objects.requireNonNull(new R().put("code", Constant.FAILURE_CODE)).put("code", Constant.UPDATE_PASSWORD_SUCCESS);
    }

    /**
     * 用户注销
     * @param map
     * @return
     */
    @RequestMapping("/logout")
    public R logout(@RequestBody Map<String, Object> map) {

        String emailNumber = (String) map.get("emailNumber");
        String code = (String) map.get("code");
        String id = (String) map.get("id");
        try {
            if (!code.equals(stringRedisTemplate.opsForValue().get(emailNumber))) {
                return Objects.requireNonNull(new R().put("code", Constant.FAILURE_CODE)).put("message",Constant.CODE_ERROR);
            }
            userService.removeById(Long.parseLong(id));
        } catch (Exception e) {
            e.printStackTrace();
            return Objects.requireNonNull(new R().put("code", Constant.SUCCESS_CODE)).put("message",Constant.LOGOUT_FAILURE);

        }
        return Objects.requireNonNull(new R().put("code", Constant.SUCCESS_CODE)).put("message",Constant.LOGOUT_SUCCESS);
    }

    /**
     * 检验token
     *
     * @param request
     * @return
     */
    @PostMapping("/checkToken")
    public R checkToken(@RequestBody HttpServletRequest request) {
        String token = request.getHeader("token");
        if (JwtUtils.checkToken(token)) {
            return Objects.requireNonNull(new R().put("code", Constant.SUCCESS_CODE)).put("message", Constant.TOKEN_SUCCESS);
        }
        return Objects.requireNonNull(new R().put("code", Constant.FAILURE_CODE)).put("message", Constant.TOKEN_FAILURE);
    }

    /**
     * 我的点赞
     * @param id
     * @return
     */
    @GetMapping("/findMyLikesByUserId/{id}")
    public R findMyLikesByUserId(@PathVariable Integer id){
        System.out.println(id);
        List<VideoEntity> list = videoService.findMyLikesByUserId(id);
        if (list.size()<1){
            return Objects.requireNonNull(new R().put("code", Constant.FAILURE_CODE)).put("message",Constant.SEARCH_FAILURE);
        }
        return Objects.requireNonNull(new R().put("code", Constant.SUCCESS_CODE).put("message", Constant.SEARCH_SUCCESS)).put("list",list);
    }
    /**
     * 我的收藏
     * @param id
     * @return
     */
    @GetMapping("/findMyCollectByUserId/{id}")
    public R findMyCollectByUserId(@PathVariable Integer id){
        List<VideoEntity> list = videoService.findMyCollectByUserId(id);
        if (list.size()<1){
            return Objects.requireNonNull(new R().put("code", Constant.FAILURE_CODE)).put("message",Constant.SEARCH_FAILURE);
        }
        return Objects.requireNonNull(new R().put("code", Constant.SUCCESS_CODE).put("message", Constant.SEARCH_SUCCESS)).put("list",list);

    }
    /**
     * 我的关注
     * @param id
     * @return
     */
    @GetMapping("/findMyConcernByUserId/{id}")
    public R findMyConcernByUserId(@PathVariable Integer id){
        List<UserEntity> list = userConcernsService.findMyConcernByUserId(id);
        if (list.size()<1){
            return Objects.requireNonNull(new R().put("code", Constant.FAILURE_CODE)).put("message",Constant.SEARCH_FAILURE);
        }
        return Objects.requireNonNull(new R().put("code", Constant.SUCCESS_CODE).put("message", Constant.SEARCH_SUCCESS)).put("list",list);

    }

}
